/*eslint-disable*/

/**
 * 数组去重输出，不修改源数组
 * ```
 * @param SourceArray : Array 需要去重的数据源
 * @param {{
 * Refuse_Null: boolean,
 * Refuse_Undefined: boolean,
 * Refuse_EmptyArray:  boolean,
 * Data_StringFullEqual_NoAdd_NotCaseSensitive: boolean,
 * Data_NumberCountContentEqual_NoAdd_NotMatchCountSymbolRecordWay: boolean,
 * Function_EqualName_NoAdd_NotCaseSensitive: boolean,
 * AsyncFunction_EqualName_NoAdd_NotCaseSensitive: boolean
 * }} [option] : Object 去重操作参数
 *
 * @return Array
 *
 * @description option 参数对象属性
 *```
 * @description Refuse_Null: true，拒绝Null，布尔值
 * ```
 * @description Refuse_Undefined: true，拒绝Undefined，布尔值
 * ```
 * @description Refuse_EmptyObject: true，拒绝空对象，布尔值
 * ```
 * @description Refuse_EmptyArray: true，拒绝空数组，布尔值
 * ```
 * @description Data_StringFullEqual_NoAdd_NotCaseSensitive: true，字符串全匹配的不添加（不区分大小写），布尔值
 * ```
 * @description Data_NumberCountContentEqual_NoAdd_NotMatchCountSymbolRecordWay: true，记数符号相同的不添加（不区分记录方式），布尔值
 * ```
 * @description Function_EqualName_NoAdd_NotCaseSensitive: true，函数名称相同的不添加（不区分大小写），布尔值
 * ```
 * @description AsyncFunction_EqualName_NoAdd_NotCaseSensitive: true，异步函数名称相同的不添加（不区分大小写），布尔值
 * ```
 * */
function arrayRemoveDump(SourceArray, option) {
    let FinalArrayOutput;
    let currentNeedComp;
    if (Object.prototype.toString.call(SourceArray) === '[object Array]' && SourceArray.length > 0) {
        let useOption = false;
        let OptionData = {};
        if (Object.prototype.toString.call(option) === '[object Object]') {
            for (let chkItem in option) {
                switch (chkItem.toLowerCase()) {
                    case 'refuse_null':
                        if (Object.prototype.toString.call(option[chkItem]) === '[object Boolean]') {
                            OptionData.Refuse_Null = option[chkItem];
                        }
                        useOption = true;
                        break;
                    case 'refuse_undefined':
                        if (Object.prototype.toString.call(option[chkItem]) === '[object Boolean]') {
                            OptionData.Refuse_Undefined = option[chkItem];
                        }
                        useOption = true;
                        break;
                    case 'refuse_emptyarray':
                        if (Object.prototype.toString.call(option[chkItem]) === '[object Boolean]') {
                            OptionData.Refuse_EmptyArray = option[chkItem];
                        }
                        useOption = true;
                        break;
                    case 'refuse_emptyobject':
                        if (Object.prototype.toString.call(option[chkItem]) === '[object Boolean]') {
                            OptionData.Refuse_EmptyObject = option[chkItem];
                        }
                        useOption = true;
                        break;
                    case "data_stringfullequal_noadd_notcasesensitive":
                        if (Object.prototype.toString.call(option[chkItem]) === '[object Boolean]') {
                            OptionData.Data_StringFullEqual_NoAdd_NotCaseSensitive = option[chkItem];
                        }
                        useOption = true;
                        break;
                    case "data_numbercountcontentequal_noadd_notmatchcountsymbolrecordway":
                        if (Object.prototype.toString.call(option[chkItem]) === '[object Boolean]') {
                            OptionData.Data_NumberCountContentEqual_NotMatchCountSymbolRecordWay = option[chkItem];
                        }
                        useOption = true;
                        break;
                    case "function_equalname_noadd_notcasesensitive":
                        if (Object.prototype.toString.call(option[chkItem]) === '[object Boolean]') {
                            OptionData.Function_EqualName_NoAdd_NotCaseSensitive = option[chkItem];
                        }
                        useOption = true;
                        break;
                    case "asyncfunction_equalname_noadd_notcasesensitive":
                        if (Object.prototype.toString.call(option[chkItem]) === '[object Boolean]') {
                            OptionData.AsyncFunction_EqualName_NoAdd_NotCaseSensitive = option[chkItem];
                        }
                        useOption = true;
                        break;
                    default:
                        console.info("出现未知的配置选项，该选项不生效。");
                        break;
                }
            }
        }
        FinalArrayOutput = [];
        for (let num1 = 0; num1 < SourceArray.length; num1++) {
            currentNeedComp = SourceArray[num1];
            if (FinalArrayOutput.length === 0) {
                FinalArrayOutput.push(currentNeedComp);
            }
            for (let num2 = 0; num2 < SourceArray.length; num2++) {
                if (num1 === num2) continue;
                if (currentNeedComp !== SourceArray[num2]) {
                    let cct = SourceArray[num2];
                    let dff = true;
                    for (let tmp in FinalArrayOutput) {
                        switch (Object.prototype.toString.call(FinalArrayOutput[tmp])) {
                            case "[object Number]":
                                if (useOption) {
                                    if (OptionData.Data_NumberCountContentEqual_NotMatchCountSymbolRecordWay) {
                                        if (Object.prototype.toString.call(cct) === '[object String]') {
                                            if (FinalArrayOutput[tmp] === parseInt(cct)) dff = false;
                                        }
                                        if (FinalArrayOutput[tmp] === cct) dff = false;
                                    } else {
                                        if (FinalArrayOutput[tmp] === cct) dff = false;
                                    }
                                } else {
                                    if (cct === FinalArrayOutput[tmp]) dff = false;
                                }
                                break;
                            case "[object String]":
                                if (useOption) {
                                    if (OptionData.Data_StringFullEqual_NoAdd_NotCaseSensitive) {
                                        if (Object.prototype.toString.call(cct) === '[object String]') {
                                            if (cct.toLowerCase() === FinalArrayOutput[tmp].toLowerCase()) dff = false;
                                        }
                                        if (Object.prototype.toString.call(cct) === '[object Number]') {
                                            if (String(cct).toLowerCase() === FinalArrayOutput[tmp].toLowerCase()) dff = false;
                                        }
                                    } else {
                                        if (cct === FinalArrayOutput[tmp]) dff = false;
                                    }
                                } else {
                                    if (cct === FinalArrayOutput[tmp]) dff = false;
                                }
                                break;
                            case "[object Object]":
                                if (Object.prototype.toString.call(cct) === '[object Object]') {
                                    let cp1 = false;
                                    let cp2 = false;
                                    for (let cpx1 in cct) {
                                        cp1 = true;
                                        break;
                                    }
                                    for (let cpx2 in FinalArrayOutput[tmp]) {
                                        cp2 = true;
                                        break;
                                    }
                                    if (cp1 === cp2) {
                                        dff = false;
                                    }
                                }
                                break;
                            case "[object Array]":
                                if (Object.prototype.toString.call(cct) === '[object Array]') {
                                    if (cct.length === FinalArrayOutput[tmp].length) dff = false;
                                }
                                break;
                            case "[object Function]":
                                if (Object.prototype.toString.call(cct) === "[object Function]") {
                                    if (useOption) {
                                        if (OptionData.Function_EqualName_NoAdd_NotCaseSensitive) {
                                            if (cct.name.toLowerCase() === FinalArrayOutput[tmp].name.toLowerCase()) dff = false;
                                        } else {
                                            if (cct.name === FinalArrayOutput[tmp].name) dff = false;
                                        }
                                    } else {
                                        if (cct.name === FinalArrayOutput[tmp].name) dff = false;
                                    }
                                }
                                break;
                            case "[object AsyncFunction]":
                                if (Object.prototype.toString.call(cct) === "[object AsyncFunction]") {
                                    if (useOption) {
                                        if (OptionData.AsyncFunction_EqualName_NoAdd_NotCaseSensitive) {
                                            if (cct.name.toLowerCase() === FinalArrayOutput[tmp].name.toLowerCase()) dff = false;
                                        } else {
                                            if (cct.name === FinalArrayOutput[tmp].name) dff = false;
                                        }
                                    } else {
                                        if (cct.name === FinalArrayOutput[tmp].name) dff = false;
                                    }
                                }
                                break;
                            default:
                                if (cct === FinalArrayOutput[tmp]) {
                                    dff = false;
                                }
                                break;
                        }
                    }
                    if (dff) {
                        if (useOption) {
                            let confirmAdd = true;
                            switch (Object.prototype.toString.call(cct)) {
                                case "[object Undefined]":
                                    if (OptionData.Refuse_Undefined) confirmAdd = false;
                                    break;
                                case "[object Null]":
                                    if (OptionData.Refuse_Null) confirmAdd = false;
                                    break;
                                case "[object Object]":
                                    if (OptionData.Refuse_EmptyObject) {
                                        let ccp1 = true;
                                        for (let cpp1 in cct) {
                                            ccp1 = false;
                                            break;
                                        }
                                        if (ccp1) confirmAdd = false;
                                    }
                                    break;
                                case "[object Array]":
                                    if (OptionData.Refuse_EmptyArray) {
                                        if (cct.length === 0) confirmAdd = false;
                                    }
                                    break;
                            }
                            if (confirmAdd) FinalArrayOutput.push(cct);
                        } else {
                            FinalArrayOutput.push(cct);
                        }
                    }
                }
            }
        }
    }
    return FinalArrayOutput;
}

/**
 * 擦除数组中匹配的数据
 * ```
 * @name EraseMatchArrayItems
 * @param sourceArray : Array 需要操作的数组数据源
 * @param needEraseItem : any 指定需要擦除的数据
 * @param notModifySourceArray : boolean 不更改源数组
 * @return Array|undefined
 * */
function EraseMatchArrayItems(sourceArray, needEraseItem, notModifySourceArray) {
    if (typeof notModifySourceArray !== "boolean") {
        notModifySourceArray = false;
    }
    if (Object.prototype.toString.call(sourceArray) !== "[object Array]") {
        throw new Error("sourceArray Argument must be an array");
    }

    function deepCopy(source) {
        var cp1;
        var cp2;
        try {
            cp1 = JSON.stringify(source);
            cp2 = JSON.parse(cp1);
            return cp2;
        } catch (e) {
            return source;
        }
    }

    if (needEraseItem !== undefined) {
        var final = [];
        var stopLoop = false;
        while (true) {
            var funcResult = undefined;
            try {
                sourceArray.forEach(function (value, index, array) {
                    switch (typeof needEraseItem) {
                        case "function":
                            if (Object.prototype.toString.call(needEraseItem) === "[object Function]") {
                                funcResult = needEraseItem(value);
                                if (funcResult !== undefined) {
                                    if (typeof funcResult === "boolean") {
                                        if (funcResult) {
                                            if (!notModifySourceArray) {
                                                throw index;
                                            }
                                        } else {
                                            if (notModifySourceArray) {
                                                final.push(deepCopy(value));
                                            }
                                        }
                                    }
                                }
                            } else {
                                throw new Error("is Only Support Not Async Functions!");
                            }
                            break;
                        case "string":
                            if (String(needEraseItem).toString() === String(value).toString()) {
                                if (!notModifySourceArray) {
                                    throw index;
                                }
                            } else {
                                if (notModifySourceArray) {
                                    final.push(deepCopy(value));
                                }
                            }
                            break;
                        case "number":
                            if (Number(needEraseItem).valueOf() === Number(value).valueOf()) {
                                if (!notModifySourceArray) {
                                    throw index;
                                }
                            } else {
                                if (notModifySourceArray) {
                                    final.push(deepCopy(value));
                                }
                            }
                            break;
                        default:
                            throw new Error("needEraseItem is Only Support String Or Number Or Functions");
                    }
                });
                stopLoop = true;
            } catch (e) {
                stopLoop = false;
                sourceArray.splice(e, 1);
            }
            if (stopLoop) {
                break;
            }
        }
        if (notModifySourceArray) {
            return final;
        } else {
            return undefined;
        }
    } else {
        throw new Error("not Exist need Match Item");
    }
}

export {arrayRemoveDump,EraseMatchArrayItems};